/*********************************************************************************************************
**
**                                   GJB 标准测试集
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: gjb_S0101804GN_4.c
**
** 文件创建日期: 2021 年 1 月 12 日
**
** 描        述: 协议栈信息统计功能测试。编制测试用例代码，调用恰当
**               接口函数获取协议栈统计信息--
**
**               tcp。
**               该用例需要使用 tools/USR-TCP232-Test.exe 工具进行配合测试
*********************************************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>

// tcp+
#include <netinet/tcp.h>
#include <netinet/ip.h>



#ifndef TEST_IP
#define TEST_IP "192.168.80.14"
#endif
#ifndef TEST_PC_IP
#define TEST_PC_IP "192.168.80.14"
#endif

// int tcp_show();

int main()
{
    int s,on = 1;
    int ret1 = -2;
    int ret2 = -2;
    int ret3 = -2;
    int ret4 = -2;
    int ret5 = -2;
    int ret6 = -2;
    int newSock;
    struct sockaddr_in addr;
    struct sockaddr_in srvr;
    socklen_t addrLen;
    char recvbuf[1024] = {0};
    int buf_len = sizeof(recvbuf);
    char sendbuf[] = "This is a message from " TEST_PC_IP;
    int buf_len1 = sizeof(sendbuf);

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == -1) {
        printf( "socket error!\n");
        return (-1);
    } else {
        printf( "socket success!\n");
    }

    ret1 = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
    if (ret1 == -1) {
        printf( "setsockopt error!\n");
        return (-1);
    } else {
        printf( "setsockopt success!\n");
    }

    socklen_t size = sizeof(on);
    ret6 = getsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, &size);
    if (ret6 == -1) {
        printf( "getsockopt error!\n");
        return (-1);
    } else {
        printf( "getsockopt success!\n");
    }

    memset(&srvr, 0, sizeof(srvr));

    srvr.sin_family = AF_INET;
    srvr.sin_port = htons(9999);
    srvr.sin_addr.s_addr =inet_addr(TEST_IP);

    ret2 = bind(s, (struct sockaddr *)&srvr, sizeof(srvr));
    if (ret2 == -1) {
        printf( "bind error!\n");
        return (-1);
    } else {
        printf( "bind success!\n");
    }

    ret3 = listen(s, 10);
    if (ret3 == -1) {
        printf( "listen error!\n");
        return (-1);
    } else {
        printf( "listen success!\n");
    }

    memset(&addr, 0, sizeof(addr));

    addrLen = sizeof (struct sockaddr);

    printf("please start PC TCP client and push \"start\"\n");

    newSock = accept(s,  (struct sockaddr *)&addr, &addrLen);
    if (newSock == -1) {
        printf( "accept error!\n");
        return (-1);
    } else {
        printf( "accept success!\n");
    }

    ret4 = recv(newSock, recvbuf, buf_len, 0);
    if (ret4 == -1) {
        printf( "recv error!\n");
        return (-1);
    } else {
        printf("recvbuf is %s\n",recvbuf);
        printf( "recv success!\n");
    }

    ret5 = send(newSock, sendbuf, buf_len1, 0);
    if (ret5 == -1) {
        printf( "send error!\n");
        return (-1);
    } else {
        printf( "send success!\n");
    }

    printf("display TCP information:\n");
    // tcp_show();
    system("netstat -t -na");

    return (0);
}

// int tcp_show(){
//     int sock = socket(AF_INET, SOCK_STREAM, 0);
//     if (sock == -1) {
//         perror("socket");
//         exit(1);
//     }

//     struct tcp_info tcpinfo;
//     socklen_t len = sizeof(tcpinfo);
//     if (getsockopt(sock, IPPROTO_TCP, TCP_INFO, &tcpinfo, &len) == -1) {
//         perror("getsockopt");
//         close(sock);
//         exit(1);
//     }

//     printf("TCP Statistics:\n");
//     printf("  RTT: %u ms\n", tcpinfo.tcpi_rtt);
//     printf("  RTO: %u ms\n", tcpinfo.tcpi_rto);
//     printf("  Send buffer size: %u bytes\n", tcpinfo.tcpi_rcv_mss);
//     printf("  Receive buffer size: %u bytes\n", tcpinfo.tcpi_rcv_mss);
//     printf("  Number of retransmissions: %u\n", tcpinfo.tcpi_total_retrans);

//     close(sock);
//     return 0;
// }
